package cn.kgc.vue.aspects;

import cn.hutool.json.JSONUtil;
import cn.kgc.vue.annotation.LogAnnotation;
import cn.kgc.vue.entity.LogInfo;
import cn.kgc.vue.entity.User;
import cn.kgc.vue.mapper.UserMapper;
import cn.kgc.vue.service.LogInfoService;
import cn.kgc.vue.utils.IpUtil;
import cn.kgc.vue.utils.JWTUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * @Author 张航
 * @Date 2024/7/11
 * @Description 日志的通知类
 */
@Component
@Aspect
public class LogAspects {

@Resource
private LogInfoService logInfoService;

    @Resource
    private JWTUtil jwtUtil;
    @Autowired
    private UserMapper userMapper;



    @Pointcut("@annotation(cn.kgc.vue.annotation.LogAnnotation)")
    public void point(){}



    //环绕通知 实现操作日志的记录
@Around("point()")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {

    //获取token  url
    //先拿到reque
    ServletRequestAttributes servletRequestAttributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = servletRequestAttributes.getRequest();

    String token = request.getHeader("authorization");
    Map<String, Object> claims = jwtUtil.getClaims(token);
    Integer id = (Integer) claims.get("uid");

    LambdaQueryWrapper<User> lambda = new QueryWrapper<User>().lambda();
    lambda.eq(User::getId, id)
            .select(User::getUsername,User::getVersion);

    User user = userMapper.selectOne(lambda);
    String username = user.getUsername();
    String ip = IpUtil.getIp(request);
    String requestURI = request.getRequestURI();


    //方法的耗时
    long start = System.currentTimeMillis();
    Object proceed = joinPoint.proceed();
    long end = System.currentTimeMillis();
    Integer time = Math.toIntExact((end - start));


    //操作类型
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    Method method = signature.getMethod();
    LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);
    String model = annotation.model();
    String operationType = annotation.operation().getOperationType();



    //方法参数
    String params="";
    Object[] args = joinPoint.getArgs();
    if (ObjectUtils.isNotEmpty(args)) {
         params = JSONUtil.toJsonStr(args);
    }

    LogInfo logInfo = new LogInfo();
    logInfo.setUsername(username);
    logInfo.setIp(ip);
    logInfo.setParams(params);
    logInfo.setUrl(requestURI);
    logInfo.setDescription(operationType);
    logInfo.setModel(model);
    logInfo.setTimeConsuming(time);

    logInfoService.save(logInfo);


    return proceed;
    }



}
